# -*- coding: utf-8 -*-
"""
Created on Mon Feb  3 23:00:25 2020

@author: CHD
"""
from sklearn.metrics import accuracy_score,f1_score,roc_auc_score,recall_score,precision_score

def cm_plot(y, yp, savePath = None):
  '''
  真实，预测
  '''
  from sklearn.metrics import confusion_matrix #导入混淆矩阵函数
  cm = confusion_matrix(y, yp) #混淆矩阵
  import matplotlib.pyplot as plt #导入作图库
  plt.matshow(cm, cmap=plt.cm.Greens) #画混淆矩阵图，配色风格使用cm.Greens，更多风格请参考官网。
  plt.colorbar() #颜色标签
  #plt.figure(figsize=(2.8,2.2))
  for x in range(len(cm)): #数据标签
    for y in range(len(cm)):
      plt.annotate(cm[y,x], xy=(x, y), horizontalalignment='center', verticalalignment='center', fontsize=16)
  plt.ylabel('True label',fontsize=10) #坐标轴标签
  plt.xlabel('Predicted label',fontsize=10) #坐标轴标签  
  plt.rcParams['savefig.dpi'] = 60 #图片像素
  plt.rcParams['figure.dpi'] = 60 #分辨率
  plt.savefig(savePath)
  plt.show()
  return plt


def roc_plot(y,yp):
    import matplotlib.pyplot as plt #导入作图库
    #plt.figure(figsize=(10,8))
    from sklearn.metrics import roc_auc_score, roc_curve #导入ROC曲线函数
    auc = roc_auc_score(y,yp)
    fpr2, tpr2, thresholds2 = roc_curve(y, yp, pos_label=1)
    plt.plot(fpr2, tpr2, linewidth=2, label = 'ROC of CNN, AUC='+str(round(auc,4)),color='red') #作出ROC曲线
    plt.xlabel('False Positive Rate') #坐标轴标签
    plt.ylabel('True Positive Rate') #坐标轴标签
    plt.ylim(0,1.05) #边界范围
    plt.xlim(0,1.05) #边界范围
    plt.legend(loc=4) #图例
#    plt.rcParams['savefig.dpi'] = 100 #图片像素
#    plt.rcParams['figure.dpi'] = 100 #分辨率
    
    plt.show() #显示作图结果
    return plt



def model_metrics(y_test, preds):
    
    #计算准确率
    acc_score = accuracy_score(y_test,preds)
    print('acc',acc_score)
    #0.75 ,计算过程(10+5)/(10+0+5+5)=0.75
    #其实也相当于np.mean(preds == y_test))
    
    #计算roc面积，但只限制于2分类，根据preds值的类型做不同处理
    #1.preds是预测的类别，而不是概率
    #根据上述例子，preds 里面的值是一个类别标签，比如'0'或者'1'
    
    #roc_auc_score1 = roc_auc_score(y_test,preds)
    #print('auc',roc_auc_score1)
    
    #0.75 计算面积如下图(文章最后)，点(0.5,1.0)，分别和(0.0)和(1.1)相连，然后求面积
    #2.preds是概率值，那么sklearn会自动调整阈值然后画出roc曲线，然后计算roc曲线面积AUC
    
    #计算召回率
    #def recall_score(y_true, y_pred, labels=None, pos_label=1, average='binary',sample_weight=None)
    #有个参数pos_label，指定计算的类别的召回率，默认为1，这里也就是查看标签为'1'的召回率
    reca_score = recall_score(y_test,preds, pos_label=1)
    print('recall_score',reca_score)
    #0.5 计算过程5/(5+5)=0.5
    
    #计算正确率
    #def precision_score(y_true, y_pred, labels=None, pos_label=1,average='binary', sample_weight=None)
    #有个参数pos_label，指定计算的类别的正确率，默认为1
    prec_score = precision_score(y_test,preds, pos_label=1)
    print('prec_score', prec_score)
    #1.0 计算过程5/(5+0) = 1.0
    
    #计算F1score
    #def f1_score(y_true, y_pred, labels=None, pos_label=1, average='binary',sample_weight=None)
    #使用的是调和平均 harmonic mean,F1 = 2 * (precision * recall) / (precision + recall)
    f1_sc = f1_score(y_test,preds, pos_label=1)
    print("f1_score", f1_sc)
    #0.666666666667 计算过程 2(1*0.5)/(1+0.5) = 1/1.5 = 0.666666666667
    #绘制roc图像
    return acc_score, reca_score, prec_score, f1_sc